package cn.shengchao.examstar.ai.domain.valueobject;

import lombok.Getter;

import java.time.LocalDateTime;
import java.util.Objects;

/**
 * 学习期间值对象
 */
@Getter
public class StudyPeriod {
    
    private final LocalDateTime startTime;
    private final LocalDateTime endTime;
    
    private StudyPeriod(LocalDateTime startTime, LocalDateTime endTime) {
        if (startTime == null) {
            throw new IllegalArgumentException("开始时间不能为空");
        }
        if (endTime == null) {
            throw new IllegalArgumentException("结束时间不能为空");
        }
        if (endTime.isBefore(startTime)) {
            throw new IllegalArgumentException("结束时间不能早于开始时间");
        }
        if (endTime.equals(startTime)) {
            throw new IllegalArgumentException("结束时间不能等于开始时间");
        }
        
        this.startTime = startTime;
        this.endTime = endTime;
    }
    
    /**
     * 创建学习期间
     */
    public static StudyPeriod of(LocalDateTime startTime, LocalDateTime endTime) {
        return new StudyPeriod(startTime, endTime);
    }
    
    /**
     * 创建从现在开始的学习期间
     */
    public static StudyPeriod startingNow(LocalDateTime endTime) {
        return new StudyPeriod(LocalDateTime.now(), endTime);
    }
    
    /**
     * 创建指定天数的学习期间
     */
    public static StudyPeriod ofDays(LocalDateTime startTime, int days) {
        if (days <= 0) {
            throw new IllegalArgumentException("学习天数必须大于0");
        }
        return new StudyPeriod(startTime, startTime.plusDays(days));
    }
    
    /**
     * 判断学习期间是否已过期
     */
    public boolean isExpired() {
        return LocalDateTime.now().isAfter(endTime);
    }
    
    /**
     * 判断学习期间是否还未开始
     */
    public boolean isNotStarted() {
        return LocalDateTime.now().isBefore(startTime);
    }
    
    /**
     * 判断学习期间是否正在进行中
     */
    public boolean isInProgress() {
        LocalDateTime now = LocalDateTime.now();
        return !now.isBefore(startTime) && !now.isAfter(endTime);
    }
    
    /**
     * 获取学习期间的总天数
     */
    public long getTotalDays() {
        return java.time.Duration.between(startTime, endTime).toDays();
    }
    
    /**
     * 获取剩余天数
     */
    public long getRemainingDays() {
        if (isExpired()) {
            return 0;
        }
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime effectiveStart = now.isAfter(startTime) ? now : startTime;
        return java.time.Duration.between(effectiveStart, endTime).toDays();
    }
    
    /**
     * 延长学习期间
     */
    public StudyPeriod extend(int days) {
        if (days <= 0) {
            throw new IllegalArgumentException("延长天数必须大于0");
        }
        return new StudyPeriod(startTime, endTime.plusDays(days));
    }
    
    /**
     * 判断是否与另一个学习期间重叠
     */
    public boolean overlapsWith(StudyPeriod other) {
        return !this.endTime.isBefore(other.startTime) && !other.endTime.isBefore(this.startTime);
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StudyPeriod that = (StudyPeriod) o;
        return Objects.equals(startTime, that.startTime) && Objects.equals(endTime, that.endTime);
    }
    
    @Override
    public int hashCode() {
        return Objects.hash(startTime, endTime);
    }
    
    @Override
    public String toString() {
        return String.format("学习期间: %s 至 %s (%d天)", 
                           startTime.toLocalDate(), 
                           endTime.toLocalDate(), 
                           getTotalDays());
    }
}